package pers.kw.config.oauth;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import pers.kw.common.spring.utils.SpringUtils;
import pers.kw.config.oauth.context.MyParamValue;
import pers.kw.config.oauth.context.MyParamValueThreadLocal;
import pers.kw.contants.AuthParamName;
import pers.kw.enums.AuthUserTypeEnum;
import pers.kw.service.UserDetailStrategy;

/**
 * token增强配置
 */
public class JwtTokenEnhancer implements TokenEnhancer {

    private static final Logger log = LoggerFactory.getLogger(JwtTokenEnhancer.class);

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
        log.info("token增强处理start...");
        MyParamValue current = MyParamValueThreadLocal.getCurrent();
        log.info("获取自定义参数信息：{}", JSON.toJSONString(current));
        log.info("OAuth2AccessToken: {}", JSON.toJSONString(oAuth2AccessToken));
        log.info("OAuth2Authentication: {}", JSON.toJSONString(oAuth2Authentication));

        MyParamValue paramValue = MyParamValueThreadLocal.getCurrent();
        String userType = paramValue.getAuthParameter(AuthParamName.USER_TYPE);
        if (StringUtils.isBlank(userType)) {
            throw new OAuth2Exception(AuthParamName.USER_TYPE + "不能为空");
        }
        if (!AuthUserTypeEnum.userTypeSet.contains(userType)) {
            throw new OAuth2Exception(AuthParamName.USER_TYPE + "错误");
        }
        AuthUserTypeEnum userTypeEnum = AuthUserTypeEnum.getEnumObjByCode(userType);
        if (userTypeEnum == null) {
            log.info("oauth服务，用户认证策略配置错误，{}:{}", AuthParamName.USER_TYPE, userType);
            throw new OAuth2Exception("认证系统异常");
        }

        try {
            UserDetailStrategy userDetailStrategy = (UserDetailStrategy) SpringUtils.getBean(Class.forName(userTypeEnum.getUserStrategy()));
            ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(userDetailStrategy.initTokenInfo(paramValue));
        } catch (ClassNotFoundException e) {
            log.error("oauth服务，用户认证策略配置获取异常", e);
            throw new OAuth2Exception("认证系统异常");
        }
        log.info("token增强处理end...");
        return oAuth2AccessToken;
    }
}
